package info.batcloud.fanli.core.service.impl;

import info.batcloud.fanli.core.dto.CityAgentDTO;
import info.batcloud.fanli.core.dto.DistrictAgentDTO;
import info.batcloud.fanli.core.constants.MessageKeyConstants;
import info.batcloud.fanli.core.entity.User;
import info.batcloud.fanli.core.entity.UserUpgradeOrder;
import info.batcloud.fanli.core.enums.*;
import info.batcloud.fanli.core.repository.UserRepository;
import info.batcloud.fanli.core.repository.UserUpgradeOrderRepository;
import info.batcloud.fanli.core.service.*;
import info.batcloud.fanli.core.settings.UserUpgradeSetting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.util.Date;
import java.util.List;

@Service
public class UserUpgradeOrderServiceImpl implements UserUpgradeOrderService, OrderService.OrderHandler<UserUpgradeOrder> {

    private static final Logger logger = LoggerFactory.getLogger(UserUpgradeOrderServiceImpl.class);

    @Inject
    private UserUpgradeOrderRepository userUpgradeOrderRepository;

    @Inject
    private SystemSettingService systemSettingService;

    @Inject
    private OrderService orderService;

    @Inject
    private UserService userService;

    @Inject
    private UserRepository userRepository;

    @Inject
    private AgentService agentService;

    @Inject
    private WalletService walletService;

    @PostConstruct
    public void init() {
        orderService.registerOrderHandler(UserUpgradeOrder.class, this);
    }

    @Override
    public synchronized long checkAndCreateUserUpgradeOrder(long userId, TimeUnit timeUnit) {
        UserService.UserLevelCheckUpgradeResult result = userService.checkUpgradeUserLevel(userId);
        if(!result.isSuccess()) {
            throw new RuntimeException("用户级别暂时无法升级");
        }
        UserService.UpgradeFee upgradeFee = null;
        for (UserService.UpgradeFee fee : result.getUpgradeFeeList()) {
            if(fee.getTimeUnit() == timeUnit) {
                upgradeFee = fee;
                break;
            }
        }
        if(upgradeFee == null) {
            throw new RuntimeException("用户级别暂时无法升级");
        }
        //如果已经存在没有支付的订单，那么进行删除
        List<UserUpgradeOrder> userUpgradeOrderList = userUpgradeOrderRepository.findByUserIdAndStatus(userId, UserLevelUpgradeOrderStatus.WAIT_PAY);
        if (userUpgradeOrderList.size() > 0) {
            for (UserUpgradeOrder order : userUpgradeOrderList) {
                order.setStatus(UserLevelUpgradeOrderStatus.DELETED);
            }
            userUpgradeOrderRepository.save(userUpgradeOrderList);
        }
        UserUpgradeOrder order = new UserUpgradeOrder();
        order.setMonth(timeUnit.month);
        order.setTotalFee(upgradeFee.getPrice());
        order.setCreateTime(new Date());
        order.setUserId(userId);
        order.setUserLevel(result.getUserLevel());
        order.setStatus(UserLevelUpgradeOrderStatus.WAIT_PAY);
        userUpgradeOrderRepository.save(order);
        return order.getId();
    }


    @Override
    @Transactional
    public void handlePayResult(UserUpgradeOrder order, OrderService.PayResult payResult) {
        if (payResult.isSuccess()) {
            //如果支付成功，那么进行用户级别的更改
            userService.changeUserLevel(order.getUserId(), order.getUserLevel(), order.getMonth());
            order.setStatus(UserLevelUpgradeOrderStatus.PAID);
            //判断是否需要会员费分配
            this.allotUpgradeFee(order, payResult);
        }
    }

    //分配会员费
    private void allotUpgradeFee(UserUpgradeOrder order, OrderService.PayResult payResult) {
        //判断是否需要PLUS会员费分配
        UserUpgradeSetting userUpgradeSetting = systemSettingService.findActiveSetting(UserUpgradeSetting.class);
        if (!userUpgradeSetting.getPlus().isAllotUpgradeFee()) {
            return;
        }
        UserUpgradeSetting.Plus plusSetting = userUpgradeSetting.getPlus();
        logger.info("进行会员费分配");
        User user = userRepository.findOne(order.getUserId());
        float feeFactor = order.getPaidFee() / plusSetting.getPricePerMonth();
        /**
         * 首先进行代理分佣
         * 1、关系代理（服务商分佣）
         * 2、县级代理
         * 3、市级代理
         * */
        //服务商分佣
        if (plusSetting.getRelationAgentRewardFee() > 0) {
            long topUserId = user.getRelationList().get(0);
            if (agentService.isAgent(topUserId, AgentType.RELATION)) {
                float fee = plusSetting.getRelationAgentRewardFee() * feeFactor;
                if (fee > 0) {
                    //如果顶级用户是代理，那么对代理进行分成
                    walletService.addMoney(topUserId, fee, WalletFlowDetailType.USER_UPGRADE_REWARD, user.getId() + "");
                }
            }
        }
        if (user.getCityId() != null) {
            //代理商分佣
            CityAgentDTO cityAgent = agentService.findCityAgentByCityId(user.getCityId());
            if (cityAgent != null && agentService.isValid(cityAgent)) {
                float fee = plusSetting.getCityAgentRewardFee() * feeFactor;
                if (fee > 0) {
                    //如果顶级用户是代理，那么对代理进行分成
                    walletService.addMoney(cityAgent.getUser().getId(), fee,
                            WalletFlowDetailType.USER_UPGRADE_REWARD, user.getId() + "");
                }
            }
            if (user.getDistrictId() != null) {
                DistrictAgentDTO districtAgent = agentService.findDistrictAgentByDistrictId(user.getDistrictId());
                if (districtAgent != null && agentService.isValid(districtAgent)) {
                    float fee = plusSetting.getDistrictAgentRewardFee() * feeFactor;
                    if (fee > 0) {
                        //如果顶级用户是代理，那么对代理进行分成
                        walletService.addMoney(districtAgent.getUser().getId(), fee,
                                WalletFlowDetailType.USER_UPGRADE_REWARD, user.getId() + "");
                    }
                }
            }
        }
        if (user.getSuperUser() == null) {
            logger.info("用户是顶级用户，不需要进行分配");
            return;
        }

        /**
         * 进行上级会员费分配
         * */
        User superUser = user.getSuperUser();
        if (plusSetting.getFatherRewardFee() > 0) {
            float fee = plusSetting.getFatherRewardFee() * feeFactor;
            if (fee > 0) {
                walletService.addMoney(superUser.getId(), fee,
                        WalletFlowDetailType.USER_UPGRADE_REWARD, user.getId() + "");
            }

        }
        /**
         * 进行上上级会员费分配
         * */
        if (plusSetting.getGrandRewardFee() > 0) {
            User grandUser = superUser.getSuperUser();
            if (grandUser != null) {
                float fee = plusSetting.getGrandRewardFee() * feeFactor;
                if (fee > 0) {
                    walletService.addMoney(grandUser.getId(), fee,
                            WalletFlowDetailType.USER_UPGRADE_REWARD, user.getId() + "");
                }
            }
        }

        if (plusSetting.getCarrierRewardFee() <= 0) {
            return;
        }

        List<Long> relationIds = user.getRelationList();
        /**
         * 运营商奖励金分配
         * */
        //读取出其所属的第一个运营商
        List<Long> carrierIds = userService.filterUserLevelUserIds(relationIds, UserLevel.CARRIER);
        if (carrierIds.size() == 0) {
            //说明不存在运营商，则返回
            return;
        }
        long lastCarrierId = carrierIds.get(carrierIds.size() - 1);
        User carrier = userRepository.findOne(lastCarrierId);
        if (carrier == null) {
            logger.error("运营商没有找到，id:" + lastCarrierId);
            return;
        }
        //运营商可以是运营总监，奖励金也是不一样的
        float carrierFee = (carrier.getLevel() == UserLevel.CARRIER
                ? plusSetting.getCarrierRewardFee()
                : plusSetting.getChiefRewardFee()) * order.getPaidFee();
        if (carrierFee > 0) {
            walletService.addMoney(carrier.getId(), carrierFee * feeFactor,
                    WalletFlowDetailType.USER_UPGRADE_REWARD, user.getId() + "");
        }
        //父运营商分配
        User superCarrier = carrier.getSuperUser();
        if (superCarrier == null) {
            return;
        }
        float superCarrierFee = (superCarrier.getLevel() == UserLevel.CARRIER
                ? plusSetting.getCarrierSuperRewardFee()
                : plusSetting.getCarrierSuperRewardFee()) * order.getPaidFee();
        if (superCarrierFee > 0) {
            walletService.addMoney(superCarrier.getId(), superCarrierFee * feeFactor,
                    WalletFlowDetailType.USER_UPGRADE_REWARD, user.getId() + "");
        }

    }

    @Override
    public OrderService.CheckPayResult checkPay(UserUpgradeOrder order) {
        OrderService.CheckPayResult result = new OrderService.CheckPayResult();
        if (order.getStatus() != UserLevelUpgradeOrderStatus.WAIT_PAY) {
            result.setSuccess(false);
            result.setCode(MessageKeyConstants.USER_LEVEL_UPGRADE_ORDER_STATUS_IS_NOT_WAIT_PAY);
        } else {
            result.setSuccess(true);
        }
        return result;
    }

    @Override
    public String getContent(UserUpgradeOrder order) {
        return order.getUserLevel().getTitle() + "会员订购_" + order.getMonth() + "个月";
    }

    @Override
    public String getTitle(UserUpgradeOrder order) {
        return order.getUserLevel().getTitle() + "会员订购_" + order.getMonth() + "个月";
    }

    @Override
    public String getStatusTitle(UserUpgradeOrder order) {
        return order.getStatus().getTitle();
    }

    @Override
    public boolean isCanPay(UserUpgradeOrder order) {
        return order.getStatus() == UserLevelUpgradeOrderStatus.WAIT_PAY;
    }
}
